package com.leenmvc.core.utils.dynamic;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class ClassLoaderUtil {

    private final static Logger log = LoggerFactory.getLogger(ClassLoaderUtil.class);

    private List<Class> loadClassByLoader(ClassLoader load) throws Exception {
        Enumeration<URL> urls = load.getResources("");
        log.info(""+urls.toString());
        //放所有类型
        List<Class> classes = new ArrayList<>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            log.info("urls="+ url.getPath());
            //文件类型
            if (url.getProtocol().equals("file")) {
                loadClassByPath(null, url.getPath(), classes, load);
            }
        }
        return classes;
    }

    // 通过文件路径加载所有类 root 主要用来替换path中前缀（除包路径以外的路径）
    private void loadClassByPath(String root, String path, List<Class> list, ClassLoader load) {
        File f = new File(path);
        if (root == null) root = f.getPath();
        //判断是否是class文件
        if (f.isFile() && f.getName().matches("^.*\\.class$")) {
            try {
                String classPath = f.getPath();
                //截取出className 将路径分割符替换为.（windows是\ linux、mac是/）
                String className = classPath.substring(root.length() + 1, classPath.length() - 6).replace("/", ".").replace("\\", ".");
                list.add(load.loadClass(className));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else {
            File[] fs = f.listFiles();
            if (fs == null) return;
            for (File file : fs) {
                loadClassByPath(root, file.getPath(), list, load);
            }
        }
    }

    /**
     * 获取所有类名
     *
     * @return 字符串数组
     * @throws Exception
     */
    public List<Class<?>> getAllClassNames(String endWith) {
        List<Class> classes = null;
        try {
            classes = loadClassByLoader(this.getClass().getClassLoader());
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<Class<?>> stringList = new ArrayList<>();
        for (int i = 0; i < classes.size(); i++) {
            String className = classes.get(i).toString();
            Class className2 = classes.get(i);
            if (className.endsWith(endWith)) {
                stringList.add(className2);
            }
        }
        return stringList;
    }


}
